const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")

const WEAPONS = require("./weapons.js");

const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 254,   // 209  239   269   299
        fixdefence: 19.75, // 16   19  21  23
        fixedAtt: 16.75,   //  14   16   18  19
        reaction : 19.75,  // 16  19   21   23
        attRate: 4.957,  // 4.1   4.7   5.3  5.8
        hpRate: 4.957,   // 4.1  4.7  5.3  5.8
        criticalRate: 3.3,   //  2.7  3.1   3.5   3.9
        criticalStrike: 6.6,  //  5.4  6.2  7  7.8
        defRate: 6.2,   //  5.1  5.8  6.6   7.3
        charging: 5.5  //  4.5   5.2   5.8   6.5
    }
}


const CLIPDATA = CLIPDATA_TYPE.max
// 胡桃标准毕业面板(吃双水精1护膜) 266精 3.1w血 87.5/243
// 胡桃极限毕业面板(吃双水精1护膜) 280精 3.1w血 98.3/294.5
let fs = require("fs")
const CONFIG = {
    chance: 25,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        criticalStrike: 62.2,
        dmgRate: 46.6,
        reaction: 187,
        // hpRate: 46.6,
    },
    clips: ["hpRate", "reaction", "criticalRate", "criticalStrike"],
    clips_initial: [
        ["reaction", "hpRate", "criticalRate", "criticalStrike"],
        ["reaction", "hpRate", "criticalRate", "criticalStrike"],
        // ["attRate", "reaction", "criticalRate", "criticalStrike"],
        ["attRate", "hpRate", "criticalRate", "criticalStrike"],
        ["reaction", "hpRate", "criticalRate", "criticalStrike"],
        ["hpRate", "reaction", "attRate", "criticalRate"]
    ],
    reactionK : 1.5,
    buffs: [  
        { dmgRate: 33},
        // { reaction:80 + 50*3},  // 饰金
        { dmgRate:22.5, reactionDmgAdd: 0.15},  // 魔女
        // { dmgRate:50, attRate: 18, qDmgRate:-50},  // 追忆
        // { dmgRate:15, aDmgZhiRate: 0.6},  // 重击套
        { jk:20, attRate: 20 }, // 钟离
        { attRate: 20 }, // 行秋宗室
        // { attRate: 20, mqdmgRate:60, mcrate:15, attRate:48 }, // 宗室莫娜
        { hpRate: 25, dmgRate:30}, // 夜阑 双水
        // { attRate: 40, dmgRate: 50, reaction: 200},
    ]
}
// 胡夜钟莫
let charaters = {
    units : {
        name: "胡桃", 
        reaction: 0,
        charging: 100,
        defRate: 0,
        defence: 615,
        hp:15552,
        base: 106,    
        criticalRate: 5,    
        criticalStrike: 88.4,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

/*

    胡桃:  血量: 15552  双爆5/88.4  白字攻击:106
    精5灭辰: 白字攻击:454  精通221  增伤36
    魔女套: 22.5火伤 15蒸发反应增伤
    圣遗物 (词条数值为平均值)
        主: 4780血 
            副: 精通19.75 
                生命4.957 
                暴击3.3
                爆伤6.6


    胡桃(魔女 追忆 饰金)三套圣遗物和武器使用对比

    吃拐计算 千岩钟离(减抗20 攻击20) 双水25%生命 

    以下为期望伤害 即考虑暴击率的平均伤害
    饰金 因为要叠加 所以分析出来的会稍微高 因为方便计算程序是直接按照叠满的计算的
    追忆不开大 多打a重

    圣遗物副词条分配为 所有部位初始4词条 所有部位歪1次无效词条 词条数值为平均值 由程序算法分析最优分配比

    饰金套期望伤害(生命沙)
        精5灭辰  普攻1段蒸发 22590 重击蒸发 65507 q蒸发 166623        
        精1护摩  普攻1段蒸发 26872 重击蒸发 77924 q蒸发 198206        
        精5决斗对单  普攻1段蒸发 22667 重击蒸发 65730 q蒸发 167190        
    
    魔女套期望伤害
        精5灭辰(生命沙)  普攻1段蒸发 23124 重击蒸发 67057 q蒸发 170567        
        精1护摩(精通沙)  普攻1段蒸发 27368 重击蒸发 79364 q蒸发 201872        
        精5决斗对单(精通沙)  普攻1段蒸发 23225 重击蒸发 67349 q蒸发 171310        
    
    追忆套期望伤害
        精5灭辰(生命沙)  普攻1段蒸发 24019 重击蒸发 69651        
        精1护摩(精通沙)  普攻1段蒸发 28817 重击蒸发 83565         
        精5决斗对单(精通沙)  普攻1段蒸发 24422 重击蒸发 70820        
    
    饰金不如魔女 追忆魔女打法不同 各有优劣 沙漏除了灭辰都用精通沙最优
    关于绿枪: 绿枪(1精)程序如果按照叠满的数值 期望大于灭辰和决斗 但实际上很难叠满等叠满e都结束了 叠满的大特效利用率太低 实际输出低于灭辰决斗
*/

calc(calc_clips_initial());

function calc(normal) {
    let charactersDmg = [];
    let count = 0;
    Object.values(WEAPONS).forEach(weapon => {
        if(weapon.weapontype == "qiang") {
            charactersDmg.push(getDMG([charaters.units,weapon,{fixedAtt:311,...CONFIG.clips_main},normal], (data,second) => {
                count++;
                data = objValueAdd([data, ...CONFIG.buffs]);
                data.hp = data.hp*(1 + (data.hpRate||0)/100) + 4780;
                let eAttAdd = data.hp * 0.0626;  // 715  626
                if(eAttAdd > data.base*4){
                    eAttAdd = data.base*4;
                }
                data.fixedAtt += eAttAdd;
                // data.criticalRate *= 2;
                if(weapon.skill) { weapon.skill(data); }
                
                let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }
                let attack = data.base *(1 + data.attRate/100) + data.fixedAtt;
                let azDmgZhi = data.aDmgZhiRate? 0.6 * attack : 0;

                let A1Dmg = getDmg({ data, rate:0.8365}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let A1DmgRea = getDmg({ data, rate:0.8365, rea}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let AZhongDmg = getDmg({ data:{...data, dmgZhi: azDmgZhi}, rate:2.4257}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let AZhongDmgRea = getDmg({ data:{...data, dmgZhi: azDmgZhi}, rate:2.4257, rea}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                
                let A1DmgMn = getDmg({ data:{
                    ...data, criticalRate: data.criticalRate + (data.mcrate||0), dmgRate:data.dmgRate+(data.mqdmgRate||0)
                }, rate: 0.8365 }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let A1DmgReaMn = getDmg({ data:{
                    ...data, criticalRate: data.criticalRate + (data.mcrate||0), dmgRate:data.dmgRate+(data.mqdmgRate||0)
                }, rate: 0.8365, rea }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let AZhongDmgMn = getDmg({ data:{
                    ...data, criticalRate: data.criticalRate + (data.mcrate||0), dmgRate:data.dmgRate+(data.mqdmgRate||0)
                }, rate: 2.4257 }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
                let AZhongDmgReaMn = getDmg({ data:{
                    ...data, criticalRate: data.criticalRate + (data.mcrate||0), dmgRate:data.dmgRate+(data.mqdmgRate||0)
                }, rate: 2.4257, rea }).qw * reduceResistanceK(10 - (data.jk || 0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //

                let QDmgRea = getDmg({ data:{...data, dmgRate:(data.dmgRate + (data.qDmgRate||0))}, rate:6.17, rea}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv); //
    
                if(data.phyRate) { // 物理特效伤害
                    data.phyDmg = getDmg({data:{...data, dmgRate:0}, rate:data.phyRate}).qw * reduceResistanceK(10-(data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);  // 
                }
    
                // 3.2622 * 2 = 6.52
                // 6.17
                // 7.06
                // mqdmgRate:60  mcrate:15
                let point = (A1DmgRea + AZhongDmgRea) * 7 + (A1Dmg + AZhongDmg) * 2 + QDmgRea * 1 + (data.phyDmg||0);
                // if(data.qDmgRate < 0) {
                //     point = (AZhongDmgReaMn + A1DmgReaMn) * 4.5 + (AZhongDmgMn + A1DmgMn) * 2.5 + (A1DmgRea + AZhongDmgRea) * 2.5 + (A1Dmg + AZhongDmg) * 1.5 + (data.phyDmg||0);
                // }
                return {point,AZhongDmgRea, data, second, attack, dmg:{A1DmgRea,AZhongDmgRea, AZhongDmgReaMn,QDmgRea}}
            }));
        }
      
    })
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });
    console.log(charactersDmg[4]);


    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[0];
    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_0命无拐魔女毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }

    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count);
}

function getDMG(dataarr, getRet){
    let chance = CONFIG.chance;
    let _ret = [];
    for (let index = 0; index <= chance; index++) {
        let c1 = index; 
        for (let index2 = 0; index2 <= chance - index; index2++) {
            let c2 = index2;
            for (let index3 = 0; index3 <= chance-index-index2; index3++) {
                let c3 = index3;
                let c4 = chance - index - index2 - index3;
                let cs = [c1, c2, c3, c4];
                var tmpdata = {};
                CONFIG.clips.forEach((v, i) => {
                    tmpdata[v] = CLIPDATA[v] * cs[i]
                })
                _ret.push(tmpdata);
            }
        }
    }
    _ret = _ret.map(second => {
        let panel = objValueAdd([...dataarr, second]);
        return  getRet(panel, second)
    })
    _ret.sort((b,a)=> a.point-b.point)
    return _ret[0]
}

// 固定攻击力 19  防御力23 生命值299 5.3% 
function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
